#ifndef TREENODE_H
#define TREENODE_H

#ifndef NULL
    #define NULL 0
#endif

#define MAX_CHILD 4

template <typename T>
class TreeNode
{
public:
    TreeNode(T element, TreeNode * _parent = NULL)
        : data(element), parent(_parent), numChild(0)
    {
        child = new TreeNode*[MAX_CHILD];

        for (int i = 0; i < MAX_CHILD; i++)
        {
            child[i] = NULL;
        }
    }

    virtual ~TreeNode()
    {
        for (int i = 0; i < numChild; i++)
        {
            if (child[i] != NULL)
            {
                delete child[i];
            }
        }

        delete []child;
    }

    TreeNode<T> *getParent()
    {
        return parent;
    }

    TreeNode<T> *getChild(int i)
    {
        if (i >= 0 && i < numChild)
        {
            return child[i];
        }

        return NULL;
    }

    bool addChild(TreeNode<T> * node)
    {
        if (numChild < MAX_CHILD)
        {
            child[numChild++] = node;
            node->parent = this;
            return true;
        }

        return false;
    }

    void removeChild()
    {
        for (int i = 0; i < numChild; i++)
        {
            if (child[i]->getNumChild() > 0)
            {
                child[i]->removeChild();
            }

            delete child[i];
            child[i] = NULL;
        }
        numChild = 0;
    }

    T * getData(){return &data;}
    int getNumChild(){return numChild;}

protected:
    T data;
    TreeNode<T> * parent;
    int numChild;
    TreeNode<T> ** child;
};

#endif // TREENODE_H
